# -*- coding: utf-8 -*-
import cherrypy

__all__ = ['MemcachedTool']

class MemcachedTool(cherrypy.Tool):
    def __init__(self):
        """ Tool that use a memcached cluster as a caching
        backend for requests to use.

        Enable this tool and provide for each path
        a suitable set of keys you want to lookup
        from the cache on each request. These values
        will be stored into ``cherrypy.request.cache``
        as a dictionary and available within your
        page handler. Once the request completes,
        the values found in ``cherrypy.request.cache``
        are stored back into the cache.        
        """
        cherrypy.Tool.__init__(self, 'before_handler',
                               self._load_from_cache,
                               priority=10)

    def _setup(self):
        cherrypy.Tool._setup(self)
        cherrypy.request.hooks.attach('before_finalize',
                                      self._cache_values,
                                      priority=80)
 
    def _load_from_cache(self, keys):
        """ Load the given ``keys`` from the cache
        right before the page handler is called.
        ``keys`` is a dictionary which provides the
        default value to use if the cache doesn't hold
        a given key.

        The cached values are then stored into
        ``cherrypy.request.cache`` as a dictionary.
        """
        values = {}
        cache = cherrypy.engine.publish
        for k in keys:
            v = cache('get-cached-value', k)
            if v is not []:
                v = v.pop()
            if v is None:
                v = keys[k]
            values[k] = v
            
        cherrypy.request.cache = values

    def _cache_values(self):
        """ Store the dictionary from
        ``cherrypy.request.cache`` into the cache
        every time a request finishes.
        """
        try:
            values = cherrypy.request.cache
            cache = cherrypy.engine.publish
            for k in values:
                cache('cache-value', k, values[k])
        finally:
            cherrypy.request.cache = None
            delattr(cherrypy.request, 'cache')
